﻿

using IotContract.Dtos.Clients;
using IotContract.Dtos.Servers;
using IotContract.Interfaces;
using IotContract.Models.Clients;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using XT.Common.Extensions;

namespace IotClientService.Managers;
/// <summary>
/// 客户端操作入口
/// </summary>
public class ClientMainManager : IClientMainManager
{
    private readonly IEnumerable<IEquipManager> _managers;
    private readonly IConnectDataService _connectDataService;
    public ClientMainManager(IEnumerable<IEquipManager> managers,IConnectDataService connectDataService)
    { 
        _managers = managers;
        _connectDataService = connectDataService; 
    }

    
    /// <summary>
    /// 启动设备
    /// </summary>
    /// <param name="equips"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<bool> Run(List<IotEquipDto> equips)
    {

      
        // 首先根据设备协议分组
       var protoTypeDic= equips.ToLookup(x => x.ProtobufType).ToDictionary(x => x.Key, y => y.ToList());

        foreach(var type in protoTypeDic.Keys)
        {
            var manager = _managers.FirstOrDefault(x => x.ProtobufType == type);
            if(manager != null)
            {
               await  manager.Run(protoTypeDic[type]);
            }
        }

        return true;


    }
    /// <summary>
    /// 启动设备
    /// </summary>
    /// <param name="equip"></param>
    /// <returns></returns>
    public async Task<bool> Run(IotEquipDto equip)
    {
        var manager = _managers.FirstOrDefault(x => x.ProtobufType == equip.ProtobufType);
        return await manager.Run(equip);
    }
    /// <summary>
    /// 停止设备
    /// </summary>
    /// <param name="equips"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<bool> Stop(List<IotEquipDto> equips)
    {
        // 首先根据设备协议分组
        var protoTypeDic = equips.ToLookup(x => x.ProtobufType).ToDictionary(x => x.Key, y => y.ToList());

        foreach (var type in protoTypeDic.Keys)
        {
            var manager = _managers.FirstOrDefault(x => x.ProtobufType == type);
            if (manager != null)
            {
                await manager.Stop(protoTypeDic[type].Select(x=>x.Id).ToList());
            }
        }

        return true;
    }

    /// <summary>
    /// 停止设备采集
    /// </summary>
    /// <param name="programId"></param>
    /// <returns></returns>
    public async Task<bool> Stop(long programId)
    {
        foreach (var manager in _managers)
        {
            await manager.StopProgram(programId);
        }
        return true;
    }
    /// <summary>
    /// 停止所有
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<bool> Stop()
    {
        foreach(var manager in _managers)
        {
            await manager.Stop();
         
        }
        return true;
    }

    /// <summary>
    /// 推送数据
    /// </summary>
    /// <returns></returns>
    public async Task PushAndWirte()
    {
        foreach(var manager in _managers)
        {
           await manager.PushAndWriteEquips();
        }
    }


   /// <summary>
   /// 读取程序的控制指令
   /// </summary>
   /// <param name="command"></param>
   /// <param name="token"></param>
   /// <returns></returns>
    public async IAsyncEnumerable<ClientControlCommand> ReadControl(ClientRequestCommand command,CancellationToken token)
    {
        await foreach (var control in _connectDataService.ReadControl(command.ProgramId,token))
        {
            // 处理控制指令
            // 停止
            if (control.ControlType == IotContract.Enums.ProgramControlType.Stop)
            {
                foreach (var manager in _managers)
                {
                    await manager.StopProgram(command.ProgramId);
                }
            }
            // 断开
            else if (control.ControlType == IotContract.Enums.ProgramControlType.DisConnect)
            {
                if (control.EquipId > 0 || control.ProtobufType.IsNotNullOrEmpty())
                {
                    var manager = _managers.FirstOrDefault(x => x.ProtobufType == control.ProtobufType);
                    if (manager != null)
                    {
                        await manager.Stop(new List<long> { control.EquipId });
                    }
                }
            }
            // 清理离线设备
            else if (control.ControlType == IotContract.Enums.ProgramControlType.ClearConnect)
            {
                foreach (var manager in _managers)
                {
                    await manager.ClearOffline(command.ProgramId);
                }
            }
            yield return control;
        }
        // 读取控制指令
    }
       
}
